/*******************************************************************************
 * Copyright (c) 2009 IBM Corporation and others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.aseclipse.osgi.loader
{
    import flash.events.IEventDispatcher;
    import flash.events.TimerEvent;
    import flash.utils.Timer;
    
    import mx.events.StyleEvent;
    import mx.logging.ILogger;
    import mx.logging.Log;
    import mx.styles.StyleManager;
    
    /**
    * Load a single or multiple style swf(s)
    */ 
    public class BundleThemeLoader
    {
        private var log_:ILogger = Log.getLogger("BundleThemeLoader");
        public static function getInstance():BundleThemeLoader {
             return  new BundleThemeLoader();
        }
        
        public function BundleThemeLoader() {
            
        }        
        private static var total:int = 0;
        private static var processing:Boolean = false;
        private var themes:Array = [];
        private var callBack:Function;
        private var update:Boolean = false;
        
        // External flag to control the loading process
        public static var resuming:Boolean = false;
        /** 
        * Load one or multiple style swf according to parameter
        * @array "String" or "Array".
        *     String can be "a.swf;b.swf;c.swf"
        * 
        */ 
        public function load(array:*, callback:Function, update:Boolean = false):void {
            if(array == null || array.length == 0) {
                if(callback != null) {
                    callback.apply(null, null);
                    callback = null;
                }
                return;
            }
            if(!(array is String) && !(array is Array)) {
                log_.error("Can't accept input without 'String' or 'Array' type.");
                if(callback != null)
                    callback.apply(null, null);
                return;
            }
            if(array is String) {
                themes = (array as String).split(";"); 
            } else {
                themes = array as Array; 
            }
            // OSGiConstants.getInput(array);
            total += themes.length;
            callBack = callback;
            this.update = update;
            laterLoad();
        }
        
        private function laterLoad():void{
            var t:Timer = new Timer(100, 1);
            t.addEventListener(TimerEvent.TIMER_COMPLETE, function():void{
                if(processing || resuming){
                    laterLoad();
                }else{
                    startLoad();
                }
            });
            t.start();
        }
        // contain the url list
        private static var loadedThemeList:Object = new Object();
        private static function themeLoaded(url:String):Boolean {
            return loadedThemeList[url] != null;
        }
        
        private var current:String = "";
        protected function startLoad():void {
            if(themes.length>0) {
                if(Log.isDebug()) log_.debug("[startLoad] load the first theme in the list: " + themes.toString());
                current = themes.shift();
                if(current) {
                    if(current.indexOf("http://") != 0 && current.indexOf("https://") != 0) {
                    	current = BundleConstants.getURLPrefix() + current;
                    }                	
                    current = BundleConstants.updateSubfix(current);
                    if (themeLoaded(current) == false) {
                        processing = true;
                        var dis:IEventDispatcher = StyleManager.loadStyleDeclarations(current, update);
                        dis.addEventListener(StyleEvent.COMPLETE, checkCompleteHandler);
                        dis.addEventListener(StyleEvent.ERROR, errorHandler);
                        dis.addEventListener(StyleEvent.PROGRESS, progressHander);
                        return;
                    }
                }
                if(Log.isDebug()) log_.debug("[startLoad] the theme exist or null: " + current);
                laterLoad();
            } else {
            	if(Log.isDebug()) log_.debug("[startLoad] all themes loaded");
                if(callBack != null) {
                    callBack.apply(null, null);
                	callBack = null;
                }
            }
        }

        private function progressHander(event:StyleEvent):void {
        }
        
        protected function errorHandler(error:StyleEvent):void {
            log_.error(error.errorText);
            var load:IEventDispatcher = error.target as IEventDispatcher;
            load.removeEventListener(StyleEvent.ERROR, errorHandler);    
            processing = false;
            laterLoad();
        }
        
        protected function checkCompleteHandler(event:StyleEvent):void {
            log_.info("[checkCompleteHandler] load "+current+" successfully.");
            var load:IEventDispatcher = event.target as IEventDispatcher;
            load.removeEventListener(StyleEvent.COMPLETE, checkCompleteHandler);
            // fill it into cache
            loadedThemeList[current] = current;
            processing = false;
            laterLoad();
        }
    }
}
